using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Diagnostics;
using ZoneFiveSoftware.Common.Data.Fitness;

namespace FilteredStatistics.Common.Controller
{
    // This class is used to register "IActivityDataTrackProvider" objects.  In fact,
    //  as mentionned in the IActivityDataTrackProvider class, you shouldn't derive
    //  directly from IActivityDataTrackProvider but rather implement it's functions.
    //  This controller class will create a proxy object from the passed object that
    //  uses the right reflection detected functions to get the required data.  Again,
    //  please use reflection to detect the right functions instead of statically
    //  linking with the plugin's DLL.
    public class ActivityDataTrackController : IEnumerable<Guid>
    {
        private ActivityDataTrackController()
        {
        }

#region IEnumerable Members

        IEnumerator IEnumerable.GetEnumerator()
        {
            return m_DataTrackProviders.GetEnumerator();
        }

#endregion

#region IEnumerable<Guid> Members

        public IEnumerator<Guid> GetEnumerator()
        {
            return m_DataTrackProviders.Keys.GetEnumerator();
        }

#endregion

        private IActivityDataTrackProvider CreateProxyProvider(object provider)
        {
            IActivityDataTrackProvider result = null;

            try
            {
                result = new ProxyDataTrackProvider(provider);
            }
            catch (Exception e)
            {
                Debug.Assert(false, e.Message);
            }

            return result;
        }

        // Function used to register a data track provider from which a proxy object
        //  will be created.  The passed object must implement all functions from the
        //  IActivityDataTrackProvider interface.
        public void RegisterDataTrackProvider(object provider)
        {
            IActivityDataTrackProvider newProvider = null;

            if (provider is IActivityDataTrackProvider)
            {
                newProvider = provider as IActivityDataTrackProvider;
            }
            else
            {
                newProvider = CreateProxyProvider(provider);

                Debug.Assert(newProvider != null);
            }

            if (newProvider != null &&
                !m_DataTrackProviders.ContainsKey(newProvider.ReferenceId))
            {
                m_DataTrackProviders.Add(newProvider.ReferenceId, newProvider);
                newProvider.Activity = m_Activity;

                if (DataTrackProviderRegistered != null)
                {
                    DataTrackProviderRegistered(newProvider, new PropertyChangedEventArgs("DataTrackProviders"));
                }
            }
        }

        public IActivityDataTrackProvider GetProvider(Guid referenceId)
        {
            if (m_DataTrackProviders.ContainsKey(referenceId))
            {
                return m_DataTrackProviders[referenceId];
            }

            return null;
        }

        public IActivityDataTrackProvider GetDefaultProvider()
        {
            Debug.Assert(m_DataTrackProviders.Count > 0);

            Dictionary<Guid, IActivityDataTrackProvider>.ValueCollection.Enumerator enumerator = m_DataTrackProviders.Values.GetEnumerator();
            enumerator.MoveNext();

            return enumerator.Current;
        }

        // Get the instance of the controller
        public static ActivityDataTrackController Instance
        {
            get
            {
                if (m_Instance == null)
                {
                    m_Instance = new ActivityDataTrackController();
                }

                return m_Instance;
            }
        }

        public IActivity Activity
        {
            get { return m_Activity; }
            set
            {
                foreach (IActivityDataTrackProvider provider in m_DataTrackProviders.Values)
                {
                    provider.Activity = value;
                }
            }
        }

        private static ActivityDataTrackController m_Instance = null;
        private IActivity m_Activity = null;
        private Dictionary<Guid, IActivityDataTrackProvider> m_DataTrackProviders = new Dictionary<Guid, IActivityDataTrackProvider>();

        public event PropertyChangedEventHandler DataTrackProviderRegistered;
    }
}
